package at.fhooe.mc.master.clc.server.dataaccess.dao.jdo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;


import at.fhooe.mc.master.clc.server.dataaccess.ErrorUtil;
import at.fhooe.mc.master.clc.server.dataaccess.dao.ITestableDao;
import at.fhooe.mc.master.clc.server.domain.ITestable;
import at.fhooe.mc.master.clc.server.domain.jdo.BigEntityJdo;

public class TestableJdoDao implements ITestableDao
{
	// Note: currently transactions are commented out
	
	@Override
	public int save(ITestable testable)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		try
		{
//			pm.currentTransaction().begin();
			pm.makePersistent(testable);
//			pm.currentTransaction().commit();
		}
		finally
		{
//			if (pm.currentTransaction().isActive())
//			{
//				pm.currentTransaction().rollback();
//			}
			pm.close();
		}
		return 0;
	}

	@Override
	public int save(List<ITestable> testables)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		try
		{
//			pm.currentTransaction().begin();
			pm.makePersistentAll(testables);
//			pm.currentTransaction().commit();
		}
		finally
		{
//			if (pm.currentTransaction().isActive())
//			{
//				pm.currentTransaction().rollback();
//			}
			pm.close();
		}
		return 0;
	}

	@Override
	public List<? extends ITestable> loadAll(Class<? extends ITestable> type)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		Query q = pm.newQuery(type);
		List<? extends ITestable> list = null;
		
		
		try
		{
			list = (List<? extends ITestable>) q.execute();
		}
		finally
		{
			// Makes problems
//			q.closeAll();
//			pm.close();
		}
		
		return list; // TODO: This might cause problems
	}

	@Override
	public List<? extends ITestable> loadFilteredEquals(
			Class<? extends ITestable> type, String field1, Object filter1,
			String field2, Object filter2, String field3, Object filter3,
			String field4, Object filter4)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		Query q = pm.newQuery(type);
		List<? extends ITestable> list = null;
		
		try
		{
			String filterString = "";
			Map<String, String> paramValues = new HashMap<String, String>();
			
			if (field1 != null)
			{
				filterString += field1 + " == :filter1 && ";
				paramValues.put("filter1", filter1.toString());
			}
			else if (field2 != null)
			{
				filterString += field2 + " == :filter2 && ";
				paramValues.put("filter2", filter2.toString());
			}
			else if (field3 != null)
			{
				filterString += field3 + " == :filter3 && ";
				paramValues.put("filter3", filter3.toString());
			}
			else if (field4 != null)
			{
				filterString += field4 + " == :filter4 && ";
				paramValues.put("filter4", filter4.toString());
			}
			
			if (!filterString.equals(""))
			{
				// cut away the last '&&'
				filterString = filterString.substring(0, filterString.lastIndexOf("&&") - 1);
//				System.out.println("Query = " + filterString);
				q.setFilter(filterString);
				list = (List<? extends ITestable>) q.executeWithMap(paramValues);
			}
			else
			{
				list = (List<? extends ITestable>) q.execute();
			}
		}
		finally
		{
			// this makes problems on loading for some reason 
			// found this post: http://stackoverflow.com/questions/5702543/how-to-resolve-object-manager-has-been-closed-error
			// cannot really explain why, but without closing the PM it works - thus it is left like this at the moment.
//			q.closeAll();
//			pm.close();
		}
		
		
		return list; // TODO: This might cause trouble....
	}

	@Override
	public ITestable loadSpecific(Class<? extends ITestable> type, long id)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		return pm.getObjectById(type, id);
	}

	@Override
	public ITestable loadSpecific(Class<? extends ITestable> type, String id)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		return pm.getObjectById(type, id);
	}

	@Override
	public int delete(ITestable testable, Class<? extends ITestable> specificClass)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.setDetachAllOnCommit(true);
		
		try
		{
//			pm.currentTransaction().begin();
			
			ITestable test = pm.getObjectById(specificClass, testable.getId());
			
			pm.deletePersistent(test);
			
//			pm.currentTransaction().commit();
		}
		finally
		{
//			if (pm.currentTransaction().isActive())
//			{
//				pm.currentTransaction().rollback();
//			}
			pm.close();
		}
		return 0;
	}

	@Override
	public int deleteAll(List<ITestable> toBeDeleted)
	{
		for (ITestable testable : toBeDeleted)
			delete(testable, testable.getClass());
		
		return 0;
	}

}
